#include "videoeffect.h"
#include <osg\Image>
#include <osg\Texture2D>
#include <osg\Geode>
#include <osgDB\ReadFile>
#include <osg\ImageStream>
#include <osg\TextureRectangle>
#include <osg\CullFace>

namespace VrDataCore
{
	VideoEffect::VideoEffect():_loop(false)
	{}

	VideoEffect::~VideoEffect()
	{}

	void VideoEffect::buildPropertyMap()
	{}

	void VideoEffect::apply(CoreBase::ActorBase* actor)
	{
		if(!_videoLoadSuccess || !isIdle())
			return;
		osg::Node* screennode = actor->getDrawable()->getOSGNode();
		_drawable = NULL;
		if(!screennode->asGroup())
		{
			osg::Geode* geode = screennode->asGeode();
			if(geode!=NULL)
			{
				osg::Geode::DrawableList list = geode->getDrawableList();
				_drawable = list.at(0);
			}
		}
		else
		{
			QList<osg::Group*> listgroup;
			osg::Group* group = screennode->asGroup();
			listgroup.push_back(group);

			while(listgroup.size()>0)
			{
				osg::Group* frontgroup = listgroup.front();
				listgroup.pop_front();
				int num = frontgroup->getNumChildren();
				for(int j=0; j<num;++j)
				{
					screennode = frontgroup->getChild(j);
					if(!screennode->asGroup())
					{
						osg::Geode* geode = screennode->asGeode();
						if(geode)
						{
							osg::Geode::DrawableList list = geode->getDrawableList();
							_drawable = list.at(0);
						}
					}
					else
						listgroup.push_back(screennode->asGroup());		
				}
			}
		}
		if (_image)
		{
			float width = _image->s() * _image->getPixelAspectRatio();
			float height = _image->t();
			osg::TextureRectangle* texture = new osg::TextureRectangle(_image);
			texture->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP_TO_EDGE);
			texture->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP_TO_EDGE);
			_drawable->getOrCreateStateSet()->setTextureAttributeAndModes(0,texture,
				osg::StateAttribute::ON);if (_image->isImageTranslucent())
			{
				_drawable->getOrCreateStateSet()->setMode(GL_BLEND, osg::StateAttribute::ON);
				_drawable->getOrCreateStateSet()->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
			}
			_drawable->getOrCreateStateSet()->setMode(GL_LIGHTING,osg::StateAttribute::OFF);
			osg::CullFace *cf = new osg::CullFace(osg::CullFace::BACK);
			_drawable->getOrCreateStateSet()->setAttributeAndModes( cf, osg::StateAttribute::ON );

			dynamic_cast<osg::ImageStream*>(_image.get())->play();
		}
		EffectBase::apply(actor);
	}

	void VideoEffect::unApply(CoreBase::ActorBase* actor)
	{
		if(isIdle())
			return;
		dynamic_cast<osg::ImageStream*>(_image.get())->quit();
		_drawable->setStateSet(NULL);
		_image = NULL;
		EffectBase::unApply(actor);
	}

	bool VideoEffect::loadVideo(const std::string& videoname)
	{
		reset() ;
		_videoName = videoname;

		_image = osgDB::readImageFile(_videoName);
		osg::ImageStream* imagestream = dynamic_cast<osg::ImageStream*>(_image.get());
		if (imagestream) 
		{
			osg::ImageStream::AudioStreams& audioStreams = imagestream->getAudioStreams();
			//if (useAudioSink && !audioStreams.empty())
			//{
			//    osg::AudioStream* audioStream = audioStreams[0].get();
			//    osg::notify(osg::NOTICE)<<"AudioStream read ["<<audioStream->getName()<<"]"<<std::endl;
			//}
			if(!_loop)
				imagestream->setLoopingMode(osg::ImageStream::NO_LOOPING);
			else
				imagestream->setLoopingMode(osg::ImageStream::LOOPING);
			_videoLoadSuccess = true;
			return true;
		}
		return false;
	}

	int VideoEffect::getVideoWidth()
	{
		if(_image.valid())
			return _image->s() * _image->getPixelAspectRatio();
		return -1;
	}

	int VideoEffect::getVideoHeight()
	{
		if(_image.valid())
			return _image->t();
		return -1;
	}

	bool VideoEffect::isFlip()
	{
		if(_image.valid())
			return _image->getOrigin()==osg::Image::TOP_LEFT;
		return false;
	}

	double VideoEffect::getVideoLength()
	{
		if(_image.valid())
			return dynamic_cast<osg::ImageStream*>(_image.get())->getLength();
		return -1;
	}

	bool VideoEffect::isPlaying()
	{
		//if(_image.valid())
		//{
		//	osg::ImageStream::StreamStatus ss = dynamic_cast<osg::ImageStream*>(_image.get())->getStatus();
		//	return ! ss== osg::ImageStream::INVALID;
		//}
		return false;
	}

	void VideoEffect::setLoop(bool b)
	{
		_loop = b;
		if(_videoLoadSuccess)
		{
			if(!_loop)
				dynamic_cast<osg::ImageStream*>(_image.get())->setLoopingMode(osg::ImageStream::NO_LOOPING);
			else
				dynamic_cast<osg::ImageStream*>(_image.get())->setLoopingMode(osg::ImageStream::LOOPING);
		}
	}
}